package com.tinyengine.it.controller.generator;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.tinyengine.it.common.base.Result;
import com.tinyengine.it.common.utils.GenDir;
import com.tinyengine.it.service.generator.GenProjectControllerService;
import com.tinyengine.it.service.generator.GenServiceMapperService;
import com.tinyengine.it.tool.ZipUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipOutputStream;

@RestController
@RequestMapping("/interface-definition/api")
@Tag(name = "代码生成")
@RequiredArgsConstructor
public class CodeGeneratorController {

    private final GenProjectControllerService generatorService;

    private final GenServiceMapperService genServiceMapperService;

    @Operation(summary = "根据class名称获取Java代码")
    @GetMapping("/generator/javaBasedByClassName/{fileName}")
    public String javaBasedByClassName(@Valid @PathVariable String fileName, @RequestParam Integer appId) throws IOException {

        String code = generatorService.generatorJava(fileName, appId);
        return code;
    }

    @Operation(summary = "build工程,并Git提交")
    @GetMapping("/generator/project")
    public Result generatorMain(@RequestParam Integer appId) throws IOException, InterruptedException {
        return Result.success(generatorService.generatorMain(appId));
    }

    //@Operation(summary = "构建vo、实体、mapper、xml、service",
    //        parameters = {
    //                @Parameter(name = "serviceId", description = "服务ID，不传默认生成所有服务代码")}
    //)
    //@GetMapping("/generator/genServiceMapperMain")
    //public Result genServiceMapperMain() throws IOException {
    //    genServiceMapperService.GenServiceMapperMain();
    //    return Result.success();
    //}

    @Operation(summary = "下载工程代码,并build工程", description = "返回 ZIP 文件")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "成功",
                    content = @Content(mediaType = "application/zip",
                            schema = @Schema(type = "string", format = "binary"))),
            @ApiResponse(responseCode = "500", description = "服务器错误")
    })
    @PostMapping("/download/project")
    public ResponseEntity<ByteArrayResource> downloadZip(@RequestParam(required = false) String directory, @RequestParam Integer appId) throws IOException, InterruptedException {
        generatorService.generatorMain(appId);
        // 打包路径
        String optTargetPathBasedOnOS = GenDir.getSpringOptTargetPathBasedOnOS(appId);

        if (StrUtil.isNotBlank(directory)) {
            optTargetPathBasedOnOS = optTargetPathBasedOnOS + FileUtil.FILE_SEPARATOR + directory.replace("\\", FileUtil.FILE_SEPARATOR).replace("/", FileUtil.FILE_SEPARATOR);
        }
        Path sourceFolder = Paths.get(optTargetPathBasedOnOS);

        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

        try (ZipOutputStream zipOut = new ZipOutputStream(byteArrayOutputStream)) {
            // 递归压缩文件夹及其内容
            ZipUtils.zipDirectory(sourceFolder, sourceFolder.getFileName().toString(), zipOut);
        }
        // 将压缩文件作为下载响应返回
        ByteArrayResource resource = new ByteArrayResource(byteArrayOutputStream.toByteArray());

        return ResponseEntity.ok()
                .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=" + sourceFolder.getFileName() + ".zip")
                //.header(HttpHeaders.CONTENT_TYPE, "application/zip")
                //.contentType(MediaType.APPLICATION_OCTET_STREAM)
                .contentType(MediaType.parseMediaType("application/zip"))
                .body(resource);
    }
}
